package com.mydomain.Bodega;

import com.mydomain.Bodega.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.framework.EntityHome;

@Name("invIngresoHome")
public class InvIngresoHome extends EntityHome<InvIngreso> {

	@In(create = true)
	InvProveedorHome invProveedorHome;
	@In(create = true)
	SubdepartamentoHome subdepartamentoHome;

	@In(required = false, value = "#{invEgresoHome.instance.egrCodigo}")
	private long egrCodigo;

	@In(required = false, value = "#{invIngresoHome.instance.ingCodigo}")
	private long ingCodigo;

	@In(value = "#{ingresoItems}", required = false)
	private List<InvIngresoItem> listadoIngresoItems = new ArrayList<InvIngresoItem>();

	public void setInvIngresoIngCodigo(Long id) {
		setId(id);
	}

	public Long getInvIngresoIngCodigo() {
		return (Long) getId();
	}

	@Override
	protected InvIngreso createInstance() {
		InvIngreso invIngreso = new InvIngreso();
		return invIngreso;
	}

	public void wire() {
		getInstance();
		InvProveedor invProveedor = invProveedorHome.getDefinedInstance();
		if (invProveedor != null) {
			getInstance().setInvProveedor(invProveedor);
		}
		Subdepartamento subdepartamento = subdepartamentoHome
				.getDefinedInstance();
		if (subdepartamento != null) {
			getInstance().setSubdepartamento(subdepartamento);
		}
	}

	public void metodoRegistroDeAuditoria(String varOperacion,
			String varPantalla, String codigo, EntityManager em) {

		try {

			Subdepartamento subdepartamento = (Subdepartamento) getSessionContext()
					.get("usuarioLogeo");
			Auditoria auditoria = new Auditoria();
			auditoria.setAudPantalla(varPantalla);
			auditoria.setAudOperacion(varOperacion);
			auditoria.setAudFecha((new Date()));
			auditoria.setAudCodigoDeTabla(codigo);
			auditoria.setUsuario(subdepartamento.getUsuario());
			em.flush();
			em.persist(auditoria);
		} catch (Exception e) {
			// TODO: handle exception
		}

	}

	public BigDecimal metodoTotalDeIngreso() {

		BigDecimal valorTotal = new BigDecimal(0.0);
		BigDecimal valorCantadUnidad = new BigDecimal(0.0);
		if (this.listadoIngresoItems.size() > 0) {
			Iterator<InvIngresoItem> entries = this.listadoIngresoItems
					.iterator();
			while (entries.hasNext()) {
				InvIngresoItem ingresosDetalle = entries.next();
				valorCantadUnidad=ingresosDetalle.getIniCantidad()
				.multiply(ingresosDetalle.getIniCostoU());
				valorTotal = valorTotal.add(valorCantadUnidad);
			}
		}
		System.out.print("asdddddddddddddddddd"+valorTotal);
		return valorTotal.setScale(
				2,
				valorTotal.ROUND_HALF_UP);
	}

	@Override
	@Transactional
	public String persist() {
		try {

			// validar el valor total

			if (Double.parseDouble(metodoTotalDeIngreso().toString())==
				Double.parseDouble(getInstance().getIngPrecioTotal().toString())){
			if (this.listadoIngresoItems.size() > 0) {
				Iterator<InvIngresoItem> entries = this.listadoIngresoItems
						.iterator();
				Subdepartamento usuario = (Subdepartamento) super
						.getSessionContext().get("usuarioLogeo");
				String codigProveedor = getInstance().getCodigoProveedor();
				InvProveedor invProveedor = getEntityManager().find(
						InvProveedor.class, Long.parseLong(codigProveedor));
				getInstance().setInvProveedor(invProveedor);
				getInstance().setDepCodigo(
						usuario.getDepartamento().getDepCodigo());
				getInstance().setSubdepartamento(usuario);
				// Se guarda la cabecera
				
				getEntityManager().persist(getInstance());
				metodoRegistroDeAuditoria("INSERTAR", "ITEMS", String
						.valueOf(getInstance().getIngCodigo()),
						getEntityManager());

				InvIngreso invIngreso = getInstance();
				System.out.println(invIngreso.getIngCodigo());
				List<InvItemStock> listadoItemsAcutalies = new ArrayList<InvItemStock>();
				while (entries.hasNext()) {
					System.out.println("holaa*********************");
					InvIngresoItem ingresosDetalle = entries.next();
					ingresosDetalle.setInvIngreso(invIngreso);
					InvGrupo grupo = getEntityManager().find(InvGrupo.class,
							ingresosDetalle.getGruCodigo());
					AuxInvItem auxItem = getEntityManager().find(
							AuxInvItem.class, ingresosDetalle.getAuxInvItem());
					ingresosDetalle.setUndCodigo(auxItem.getInvUnidadMedida()
							.getUndCodigo());
					ingresosDetalle.setIniNombre(auxItem.getIteNombre());
					ingresosDetalle.setGrupo(grupo);
					ingresosDetalle.setIniCostoT(ingresosDetalle
							.getIniCantidad().multiply(
									ingresosDetalle.getIniCostoU()));
					ingresosDetalle.setSubdepCodigo(usuario.getSubdepCodigo());
					ingresosDetalle.setDepCodigo(usuario.getDepartamento()
							.getDepCodigo());
					InvItemStock invItem = metodoInsertarItem(auxItem,
							ingresosDetalle, usuario);
					ingresosDetalle.setInvItemStock(invItem);
					// Se guarda el dealle del ingreso
					getEntityManager().persist(ingresosDetalle);
					getEntityManager().flush();
					metodoRegistroDeAuditoria(
							"INSERTAR",
							"ITEMS_DETALLE",
							String.valueOf(ingresosDetalle.getDetalleIngreso()),
							getEntityManager());
					getFacesMessages().add("Se a gruardo el ingreso  !!!");
				}
			} else {
				getFacesMessages().add("No hay ningun items agregado no se puede guardar !!!");

			}
			}else
				getFacesMessages().add("No coinciden el valor total del ingreso no se puedo guardar !!!");
		} catch (Exception e) {
			// TODO: handle exception
		}
		return "";
	}

	// //////////////////////////////////////////////////
	// Metodo que actualiza el costo promedio por item
	// /////////////////////////////////////////////////

	@Transactional
	public InvItemStock metodoInsertarItem(AuxInvItem auxItem,
			InvIngresoItem ingresosDetalle, Subdepartamento usuario) {

		BigDecimal costoPorUnidad;
		BigDecimal totalCantidad;
		BigDecimal totalPrecio;
		BigDecimal costoPromedio;
		BigDecimal aux;
		InvItemStock item = new InvItemStock();
		// Caso en no Existe el producto en Bodega
		Query sql = getEntityManager()
				.createQuery(
						"SELECT i  from InvItemStock i where subdepCodigo = :subdepartamento and depCodigo = :departamento and iteCodigo = :codigo ")
				.setParameter("subdepartamento", usuario.getSubdepCodigo())
				.setParameter("departamento",
						usuario.getDepartamento().getDepCodigo()).setParameter(
						"codigo", auxItem.getIteCodigo());
		List listadoItemStock = sql.getResultList();
		if (sql.getResultList().size() == 0) {
			System.out.println("VAcio");
			InvItemStock itemActual = new InvItemStock();
			itemActual.setIteCodigo(auxItem.getIteCodigo());
			itemActual.setInvUnidadMedida(auxItem.getInvUnidadMedida());
			itemActual.setInvGrupo(auxItem.getInvGrupo());
			costoPorUnidad = ingresosDetalle.getIniCantidad().multiply(
					ingresosDetalle.getIniCostoU());
			itemActual.setIteCostoT(costoPorUnidad);
			itemActual.setIteCosto(ingresosDetalle.getIniCostoU());
			itemActual.setItePrecio(ingresosDetalle.getIniCostoU());
			itemActual.setIteCostoDolares(ingresosDetalle.getIniCostoU());
			itemActual.setItePrecioDolares(ingresosDetalle.getIniCostoU());
			itemActual.setIteNombre(auxItem.getIteNombre());
			itemActual.setIteDescripcion(auxItem.getIteDescripcion());
			itemActual.setIteUnidad(ingresosDetalle.getIniCantidad());
			itemActual.setDepCodigo(usuario.getDepartamento().getDepCodigo());
			itemActual.setSubdepCodigo(usuario.getSubdepCodigo());
			// System.out.println("Costo"+costoPorUnidad);
			System.out.println("CostoU" + ingresosDetalle.getIniCostoU());
			System.out.println("Cantidad" + ingresosDetalle.getIniCantidad());
			System.out.println(auxItem.getIteCodigo());
			System.out.println(auxItem.getInvGrupo().getGruCodigo());
			System.out.println(ingresosDetalle.getIniCantidad());
			getEntityManager().persist(itemActual);
			getEntityManager().flush();
			metodoRegistroDeAuditoria("INSERTAR", "STOCK", String
					.valueOf(itemActual.getItemSecuenca()), getEntityManager());
			item = itemActual;
		} else {
			InvItemStock itemActual = (InvItemStock) listadoItemStock.get(0);
			System.out.println("Si existe en la BDD");
			totalCantidad = itemActual.getIteUnidad().add(
					ingresosDetalle.getIniCantidad()); 
			
			costoPorUnidad = (ingresosDetalle.getIniCantidad()).multiply(ingresosDetalle.getIniCostoU());
			System.out.println("hasta aqui seguido el codigo costo por unidad"+costoPorUnidad);  // costo total ingreso
			System.out.println("hasta aqui seguido el codigo ingresosDetalle.getIniCantidad"+ingresosDetalle.getIniCantidad());  //cantidad ingreso
			System.out.println("hasta aqui seguido el codigo ingresosDetalle.getIniCostoU"+ingresosDetalle.getIniCostoU());  // costo por unidad ingreso
			
			System.out.println("hasta aqui seguido el codigo totalCantidad"+totalCantidad); // cantidad final total
			System.out.println("hasta aqui seguido el codigo itemActual.getIteUnidad()"+itemActual.getIteUnidad()); //cantidad actual
			System.out.println("hasta aqui seguido el codigo ingresosDetalle.getIniCantidad()"+ingresosDetalle.getIniCantidad()); //cantidad ingreso
			
			

			aux = itemActual.getIteCosto().multiply(itemActual.getIteUnidad());
			totalPrecio = aux.add(costoPorUnidad);
			//totalPrecio = itemActual.getIteCostoT().add(costoPorUnidad);
			System.out.println("hasta"+itemActual.getIteCodigo()); // aux
			System.out.println(itemActual.getIteCosto());
			System.out.println(itemActual.getIteCostoDolares());
			System.out.println(itemActual.getItePrecio());
			System.out.println("hasta aqui itemActual.getIteCostoT()"+itemActual.getIteCostoT());
			
			System.out.println("hasta aqui total cantidad"+totalCantidad);
			System.out.println("hasta aqui total precio"+totalPrecio);/////******* dato requerido
			
			costoPromedio = totalPrecio.divide(totalCantidad,BigDecimal.ROUND_UP);
			
			itemActual.setIteUnidad(totalCantidad);
			itemActual.setItePrecioDolares(ingresosDetalle.getIniCostoU());
			itemActual.setItePrecio(ingresosDetalle.getIniCostoU());
			itemActual.setIteCostoT(costoPromedio.multiply(totalCantidad));
			
			System.out.println("aqui estoy"+costoPromedio.multiply(totalCantidad));
			
			itemActual.setIteCostoDolares(costoPromedio);
			itemActual.setIteCosto(costoPromedio);
			System.out.println("costo promedio"+costoPromedio);
			getEntityManager().merge(itemActual);
			getEntityManager().flush();
			item = itemActual;
		} 
		metodoInventario(item, usuario);
		return item;
	}

	// //////////////////////////////////////////////////
	// Metodo que inserta o actualiza el inventario
	// /////////////////////////////////////////////////

	@Transactional
	public void metodoInventario(InvItemStock invItemStock,
			Subdepartamento usuario) {

		BigDecimal costoPorUnidad;
		BigDecimal totalCantidad;
		BigDecimal totalPrecio;
		BigDecimal costoPromedio;
		InvItemStock item = new InvItemStock();
		Integer numeroTransaciones;
		Inventario inventario = new Inventario();

		// Caso en no Existe el produecto en Bodega
		Query sql = getEntityManager()
				.createQuery(
						"SELECT i  from Inventario i join i.invItemStock s where i.subdepCodigo = :subdepartamento and i.depCodigo = :departamento and  s.itemSecuenca = :codigo order by i.invtransacion")
				.setParameter("subdepartamento", usuario.getSubdepCodigo())
				.setParameter("departamento",
						usuario.getDepartamento().getDepCodigo()).setParameter(
						"codigo", invItemStock.getItemSecuenca());

		List listadoItemStock = sql.getResultList();
		if (listadoItemStock.size() == 0) {
			numeroTransaciones = 1;
			System.out.println("VAcio");
			inventario.setInvIteCantidad( new BigDecimal(0));
			inventario.setInvIteCantidad(invItemStock.getIteUnidad());
			inventario.setInvtransacion(numeroTransaciones);
			inventario.setInvIteCostoDolares(invItemStock.getIteCostoDolares());
			inventario.setInvIteCostoT(invItemStock.getIteCostoT());
			inventario.setInvItemStock(invItemStock);
			inventario.setInvItePrecio(invItemStock.getItePrecio());
			inventario.setDepCodigo(invItemStock.getDepCodigo());
			inventario.setSubdepCodigo(invItemStock.getSubdepCodigo());
			inventario.setInvItePrecioDolares(invItemStock
					.getItePrecioDolares());
			inventario.setInvFecha((new Date()));
			inventario.setInvIngCodigo(getInstance().getIngCodigo());
			getEntityManager().persist(inventario);
			getEntityManager().flush();
		} else {
			Integer cantidad;
			numeroTransaciones = listadoItemStock.size();
			System.out.println("Si existe en la BDD" + numeroTransaciones);
			Inventario inventarioActual = (Inventario) listadoItemStock
					.get(numeroTransaciones - 1);
			System.out.println("Si existe en la BDD"
					+ invItemStock.getIteUnidad());
			inventario.setInvIteCantidadAnterior(inventarioActual
					.getInvIteCantidad());
			inventario.setInvIteCantidad(invItemStock.getIteUnidad());
			inventario.setInvtransacion(numeroTransaciones + 1);
			inventario.setInvIteCostoDolares(invItemStock.getIteCostoDolares());
			inventario.setInvIteCostoT(invItemStock.getIteCostoT());
			inventario.setInvItemStock(invItemStock);
			inventario.setInvItePrecio(invItemStock.getItePrecio());
			inventario.setInvItePrecioDolares(invItemStock
					.getItePrecioDolares());
			inventario.setInvFecha((new Date()));
			inventario.setDepCodigo(invItemStock.getDepCodigo());
			inventario.setSubdepCodigo(invItemStock.getSubdepCodigo());
			inventario.setInvIngCodigo(getInstance().getIngCodigo());
			inventario.setInvEgrCodigo(new Long(0));
			getEntityManager().persist(inventario);
			getEntityManager().flush();
		}

	}

	@Transactional
	public String metodoManualIngresoPorTransferencia() {
		BigDecimal sumar = BigDecimal.ZERO;
		BigDecimal sumarTotal = BigDecimal.ZERO;

		InvIngreso invIngreso = new InvIngreso();
		InvEgreso egresoCabecera = new InvEgreso();
		Subdepartamento usuario = (Subdepartamento) Contexts
				.getSessionContext().get("usuarioLogeo");

		List<InvItemStock> listadoItemsAcutalies = new ArrayList<InvItemStock>();
		List<InvEgresoItem> egresoItems = getEntityManager().createQuery(
				"SELECT i FROM  InvEgresoItem  i JOIN i.invEgreso s "
						+ " where  s.egrCodigo = :egreso ").setParameter(
				"egreso", this.egrCodigo).getResultList();
		List egreso = getEntityManager().createQuery(
				"SELECT s FROM  InvEgresoItem  i JOIN i.invEgreso s  "
						+ " where  s.egrCodigo = :egreso ").setParameter(
				"egreso", this.egrCodigo).getResultList();
		for (InvEgresoItem items : egresoItems) {
			System.out.println(items.getEgiCostoT());
			sumarTotal = sumar.add(items.getEgiCostoT()).add(sumarTotal);
		}
		if (egreso.size() > 0) {
			egresoCabecera = (InvEgreso) egreso.get(0);
		}

		// Cabcera de Ingreso
		// Se guarda la cabecera
		invIngreso.setDepCodigo(usuario.getDepartamento().getDepCodigo());
		invIngreso.setIngObservacion("INGRESO_POR_TRANSFERENCIA");
		invIngreso.setIngDescuento(egresoCabecera.getEgrDescuento());
		invIngreso.setIngIva(egresoCabecera.getEgrIva());
		invIngreso.setIngPrecioTotal(sumarTotal);
		invIngreso.setIngFecha((new Date()));
		invIngreso.setSubdepartamento(usuario);
		getEntityManager().persist(invIngreso);
		getEntityManager().flush();
		egresoCabecera.setEgrEstadoTransferencia(Boolean.TRUE);
		getEntityManager().merge(egresoCabecera);
		getEntityManager().flush();
		//

		Iterator<InvEgresoItem> entries = egresoItems.iterator();
		while (entries.hasNext()) {
			InvIngresoItem ingresosDetalle = new InvIngresoItem();
			System.out.println("holaa*********************");
			InvEgresoItem egresoDetalle = entries.next();
			ingresosDetalle.setInvIngreso(invIngreso);
			InvGrupo grupo = getEntityManager().find(InvGrupo.class,
					egresoDetalle.getGruCodigo());
			AuxInvItem auxItem = getEntityManager().find(AuxInvItem.class,
					egresoDetalle.getInvItemStock().getIteCodigo());
			ingresosDetalle.setUndCodigo(auxItem.getInvUnidadMedida()
					.getUndCodigo());
			ingresosDetalle.setIniNombre(auxItem.getIteNombre());
			ingresosDetalle.setGrupo(grupo);
			ingresosDetalle.setIniCantidad(egresoDetalle.getEgiCantidad());
			ingresosDetalle.setIniCostoU(egresoDetalle.getEgiPrecioU());
			ingresosDetalle.setSubdepCodigo(usuario.getSubdepCodigo());
			ingresosDetalle.setDepCodigo(usuario.getDepartamento()
					.getDepCodigo());
			InvItemStock invItem = metodoInsertarItem(auxItem, ingresosDetalle,
					usuario);
			ingresosDetalle.setInvItemStock(invItem);
			// Se guarda el dealle del ingreso
			getEntityManager().persist(ingresosDetalle);
			getEntityManager().flush();
		}
		return "/InvIngresoTransList.xhtml";
	}

	@Factory("ingresoItemsListado")
	public List<InvIngresoItem> egresoItemsPorTransferencia() {
		
		BigDecimal varSumar=new BigDecimal(0.00);
		if (this.ingCodigo > 0){
			
			List<InvIngresoItem> varListadoItems=getEntityManager().createQuery(
					"SELECT i FROM  InvIngresoItem  i JOIN i.invIngreso s "
					+ " where  s.ingCodigo = :ingreso ").setParameter(
			"ingreso", this.ingCodigo).getResultList();
			
		if (!varListadoItems.isEmpty()){
			
				for (InvIngresoItem invIngresoItem : varListadoItems) {
					varSumar=varSumar.add(invIngresoItem.getIniCantidad().multiply(invIngresoItem.getIniCostoU()));
				}
				getInstance().setVarTotalIngresoNeto(varSumar);
				getInstance().setVarTotalIngresoNeto(getInstance().getVarTotalIngresoNeto()
						.setScale(2,getInstance().getVarTotalIngresoNeto().ROUND_HALF_UP));		
		}
			
			return varListadoItems;
		}else
			return null;

	}

	public boolean isWired() {
		return true;
	}

	public InvIngreso getDefinedInstance() {
		return isIdDefined() ? getInstance() : null;
	}

	public List<InvIngresoItem> getInvIngresoItems() {
		return getInstance() == null ? null : new ArrayList<InvIngresoItem>(
				getInstance().getInvIngresoItems());
	}

}
